﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.IO;
using SilveR.RService;

namespace SilveR
{
    public partial class AnalysisView : UserControl
    {
        //access to the analysis object that is held within the settings tab
        private IAnalysis analysis;
        public IAnalysis Analysis
        {
            get { return analysis; }
        }

        public AnalysisView(IAnalysis analysis)
        {
            InitializeComponent();

            this.analysis = analysis;
            this.analysis.DataValidated += new DataValidatedEventHandler(analysis_DataValidated);

            tabSettings.Content = analysis;
        }

        private Guid ID;
        private RServiceClient client;
        private DateTime sw;

        public void RunAnalysis()
        {
            reportText.Visibility = System.Windows.Visibility.Collapsed;
            reportText.FontSize = 2;
            sw = DateTime.Now;

            //reset the log text
            txtLog.Text = String.Empty;

            //disable the report button
            btnReport.IsEnabled = false;

            //get a new guid for this analysis
            ID = Guid.NewGuid();

            //validate the gui
            bool guiValidated = analysis.ValidateGUI();
            if (!guiValidated) return;

            //now validate the data
            analysis.ValidateData();
        }

        private void analysis_DataValidated(object sender, DataValidatedEventArgs e)
        {
            if (e.DataValidated)
            {
                //ok, gui validated so can now automatically move to the log tab
                tabLog.IsSelected = true;

                //get the data (doing any transformations along the way)
                string[] csv = analysis.ExportData();

                txtLog.Text = txtLog.Text + "Connecting to R Server at ";
                client = new RServiceClient();

                txtLog.Text = txtLog.Text + client.Endpoint.Address.Uri.ToString() + "...";

                client.UploadCSVDataCompleted += new EventHandler<AsyncCompletedEventArgs>(client_UploadCSVDataCompleted);
                client.ExecuteRCompleted += new EventHandler<ExecuteRCompletedEventArgs>(client_ExecuteRCompleted);
                txtLog.Text = txtLog.Text + "completed." + Environment.NewLine + Environment.NewLine;

                UploadData(csv);
            }
        }


        private void UploadData(string[] csv)
        {
            if (csv != null)
            {
                txtLog.Text = txtLog.Text + "Uploading data...";
                client.UploadCSVDataAsync(ID, csv);
            }
            else
            {
                AnalyseData();
            }
        }

        private void client_UploadCSVDataCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                txtLog.Text = txtLog.Text + "completed." + Environment.NewLine + Environment.NewLine;

                AnalyseData();
            }
        }

        private void AnalyseData()
        {
            txtLog.Text = txtLog.Text + "Analysing data...";
            client.ExecuteRAsync(ID, analysis.ScriptName, analysis.GetAnalysisArguments());
        }

        private void client_ExecuteRCompleted(object sender, ExecuteRCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                txtLog.Text = txtLog.Text + "outputting" + Environment.NewLine + Environment.NewLine;
                txtLog.Text = txtLog.Text + e.Result;

                //just to make sure that an analysis has been run...
                if (ID.ToString() != new Guid().ToString())
                {
                    txtLog.Text = txtLog.Text + Environment.NewLine + Environment.NewLine + "Loading report in browser window (if popup blocker allows)..." + Environment.NewLine + Environment.NewLine;
                    string url = App.ReportsBaseURL + ID.ToString() + ".html";
                    HtmlPage.Window.Navigate(new Uri(url), "_blank");
                    btnReport.IsEnabled = true;
                }

                TimeSpan timeElapsed = DateTime.Now - sw;
                txtLog.Text = txtLog.Text + "Process took a total of " + Math.Round(timeElapsed.TotalSeconds, 2) + " seconds.";

                //scroll to the end of the textbox
                txtLog.SelectionStart = txtLog.Text.Length + 1;

                reportText.Visibility = System.Windows.Visibility.Visible;
                textAnimation.Begin();
            }
        }

        private void report_Click(object sender, RoutedEventArgs e)
        {
            string url = App.ReportsBaseURL + ID.ToString() + ".html";
            HtmlPage.Window.Navigate(new Uri(url), "_blank");
        }
    }

    public delegate void DataValidatedEventHandler(object sender, DataValidatedEventArgs e);

    public class DataValidatedEventArgs : EventArgs
    {
        private bool dataValidated;
        public bool DataValidated { get { return dataValidated; } }

        public DataValidatedEventArgs(bool dataValidated)
        {
            this.dataValidated = dataValidated;
        }
    }
}